package com.etc.order.frontend.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alipay.api.AlipayApiException;
import com.etc.order.common.alipay.AlipayBean;
import com.etc.order.common.domain.*;
import com.etc.order.common.dto.SimpleDTO;
import com.etc.order.common.enums.OrderStatusEnum;
import com.etc.order.common.enums.PayStatusEnum;
import com.etc.order.common.service.*;
import com.etc.order.frontend.dto.OrderDTO;
import com.etc.order.frontend.filter.AuthFilter;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
@Slf4j
public class OrderController {
    @Resource
    @Reference
    private OrderMasterService orderMasterService;

    @Resource
    @Reference
    private OrderDetailService orderDetailService;

    @Resource
    @Reference
    private ProductInfoService productInfoService;

    @Resource
    @Reference
    private ShoppingCartService shoppingCartService;

    @Resource
    @Reference
    private PayService payService;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    private final Gson gson = new Gson();

    @PostMapping("/order/create")
    @ResponseBody
    public synchronized SimpleDTO createOrder(@RequestBody String productListJSON) {
        User user = (User)AuthFilter.getSession().getAttribute("userInfoFrontend");
        if (user == null) {
            return new SimpleDTO(1, "请先登录", null);
        }
        OrderDTO[] orderDTOs = gson.fromJson(productListJSON, OrderDTO[].class);
        List<ProductInfo> productInfoList = new ArrayList<>();
        for (OrderDTO orderDTO : orderDTOs) {
            ProductInfo productInfo = productInfoService.getOne(orderDTO.getProductId());
            productInfoList.add(productInfo);
        }
        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setOrderId(UUID.randomUUID().toString().replace("-", ""));
        orderMaster.setBuyerName(user.getUserName());
        orderMaster.setBuyerAddress(user.getUserAddress());
        orderMaster.setBuyerPhone(user.getUserPhone());

        List<OrderDetail> orderDetailList = new ArrayList<>();
        int ctr = 0;
        double sum = 0;
        for (ProductInfo productInfo : productInfoList) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setDetailId(UUID.randomUUID().toString().replace("-", ""));
            orderDetail.setOrderId(orderMaster.getOrderId());
            orderDetail.setProductIcon(productInfo.getProductIcon());
            orderDetail.setProductId(productInfo.getProductId());
            orderDetail.setProductName(productInfo.getProductName());
            orderDetail.setProductPrice(productInfo.getProductPrice());
            orderDetail.setProductQuantity(orderDTOs[ctr].getProductQuantity());
            orderDetailList.add(orderDetail);
            if (productInfo.getProductStock() < orderDetail.getProductQuantity()) {
                return new SimpleDTO(1, "库存不足", null);
            }
            sum += orderDetail.getProductPrice().doubleValue() * (double) orderDetail.getProductQuantity();
            productInfo.setProductStock(productInfo.getProductStock() - orderDetail.getProductQuantity());
            productInfoService.decreaseStock(productInfo.getProductId(), productInfo.getProductStock());
            ctr++;
        }
        orderMaster.setOrderAmount(new BigDecimal(sum));

        if (orderMasterService.createOrderMaster(orderMaster, orderDetailList)) {
            redisTemplate.opsForValue().set("order:" + orderMaster.getOrderId(), "", 180, TimeUnit.SECONDS);
            return new SimpleDTO(0, "成功", orderMaster.getOrderId());
        } else {
            return new SimpleDTO(1, "失败", null);
        }
    }

    @GetMapping("/pay")
    @ResponseBody
    public String payCheck() {
        User user = (User)AuthFilter.getSession().getAttribute("userInfoFrontend");
        if (user == null) {
            return "<script>alert('请先登录');window.location = '/index.html'</script>";
        }
        List<ShoppingCart> carts = shoppingCartService.findByUid(user.getUid());
        if (carts.size() == 0) {
            return "<script>alert('请把想要购买的商品加入到购物车再来结账哦！');window.location = '/index.html'</script>";
        }
        return "<script>window.location = '/pay.html'</script>";
    }

    @GetMapping("/pay.html")
    public String payPage() {
        return "pay";
    }

    @GetMapping("/order/list")
    @ResponseBody
    public SimpleDTO getOrderList() {
        User user = (User)AuthFilter.getSession().getAttribute("userInfoFrontend");
        if (user == null) {
            return new SimpleDTO(1, "请先登录", null);
        }
        List<ShoppingCart> carts = shoppingCartService.findByUid(user.getUid());
        if (carts.size() == 0) {
            return new SimpleDTO(1, "购物车为空", null);
        }
        List<OrderDTO> orderDTOList = new ArrayList<>();
        for (ShoppingCart cart : carts) {
            OrderDTO orderDTO = new OrderDTO();
            orderDTO.setProductId(cart.getProductId());
            orderDTO.setProductQuantity(cart.getProductQuantity());
            orderDTOList.add(orderDTO);
        }
        return new SimpleDTO(0, "成功", orderDTOList);
    }

    @GetMapping("/order/pay")
    @ResponseBody
    public synchronized String pay(String orderId) {
        User user = (User)AuthFilter.getSession().getAttribute("userInfoFrontend");
        if (user == null) {
            return gson.toJson(new SimpleDTO(1, "请先登录", null));
        }
        OrderMaster orderMaster = orderMasterService.findByOrderId(orderId);
        AuthFilter.getSession().setAttribute("processingOrder", orderId);
        AlipayBean alipayBean = new AlipayBean();
        alipayBean.setOut_trade_no(orderId);
        alipayBean.setSubject(user.getUserName());
        alipayBean.setTotal_amount(orderMaster.getOrderAmount().toPlainString());
        alipayBean.setBody("小憨包外卖");
        String payResult;
        try {
            payResult = payService.aliPay(alipayBean);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return gson.toJson(new SimpleDTO(1, e.getErrMsg(), null));
        }
        return payResult;
    }

    @GetMapping("/paySuccess.html")
    public String paySuccess() {
        String orderId = (String) AuthFilter.getSession().getAttribute("processingOrder");
        OrderMaster orderMaster = orderMasterService.findByOrderId(orderId);
        orderMaster.setOrderStatus(OrderStatusEnum.FINISHED.getCode());
        orderMaster.setPayStatus(PayStatusEnum.SUCCESS.getCode());
        orderMaster.setUpdateTime(new Date(System.currentTimeMillis()));
        orderMasterService.update(orderMaster);
        AuthFilter.getSession().removeAttribute("processingOrder");
        User user = (User)AuthFilter.getSession().getAttribute("userInfoFrontend");
        if (user != null) shoppingCartService.deleteByUid(user.getUid());
        return "paySuccess";
    }

    @GetMapping("/payError.html")
    public String payError() {
        AuthFilter.getSession().removeAttribute("processingOrder");
        return "payError";
    }
}
